
const numberReg = /^-?[1-9][0-9]?.?[0-9]*$/
const intReg = /^-?[1-9][0-9]*$/
const phoneReg = /^1(3|4|5|6|7|8|9)\d{9}$/
const emailReg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
const pwdReg = /^.{6,16}$/
const inviteCodeReg = /^[a-zA-Z0-9]{6,16}$/
const ip4Reg =  /^([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$/
		
export default {
	isNull:function(val){
		if(val==null || val=="" || val=='undefined'){
		    return true;
		}
		return false;
	},
	isNumber: function(val) {
		return numberReg.test(val)
	},
	isInt: function(val) {
		return intReg.test(val)
	},
	isPhone: function(val) {
		return phoneReg.test(val)
	},
	/**
	* @description 判断数据是否为座机号(固定电话)
	* @param {String} str_data 待校验的数据
	* @returns {Boolean}, true:是座机号
	**/
	isTelephone : function (str_data) {
		str_data = str_data || String(this);
		if (str_data.match(/^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/) == null) {
			return false;
		} else {
			return true;
		}
	},
	isEmail: function(val) {
		return emailReg.test(val)
	},
	isPwd: function(val) {
		return pwdReg.test(val)
	},
	isInviteCode: function(val) {
		return inviteCodeReg.test(val)
	},
	checkCode: function (val) {
	    let p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
	    let factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
	    let parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ];
	    let code = val.substring(17);
	    if(p.test(val)) {
	        let sum = 0;
	        for(let i=0;i<17;i++) {
	            sum += val[i]*factor[i];
	        }
	        if(parity[sum % 11] == code.toUpperCase()) {
	            return true;
	        }
	    }
	    return false;
	},
	checkDate:function (val) {
	    let pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/;
	    if(pattern.test(val)) {
	        let year = val.substring(0, 4);
	        let month = val.substring(4, 6);
	        let date = val.substring(6, 8);
	        let date2 = new Date(year+"-"+month+"-"+date);
	        if(date2 && date2.getMonth() == (parseInt(month) - 1)) {
	            return true;
	        }
	    }
	    return false;
	},
	checkProv: function (val) {
	    let pattern = /^[1-9][0-9]/;
	    let provs = {11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门"};
	    if(pattern.test(val)) {
	        if(provs[val]) {
	            return true;
	        }
	    }
	    return false;
	},
	/**
	 * 校验身份证
	 * **/
	isIdcard: function (val) {
	    if(this.checkCode(val)) {
	        let date = val.substring(6,14);
	        if(this.checkDate(date)) {
	            if(this.checkProv(val.substring(0,2))) {
	                return true;
	            }
	        }
	    }
	    return false;
	},
	/**
	* @description 判断是否为统一社会信用代码
	* @param {String} str_data 待校验的数据
	* @returns {Boolean}, true:社会信用代码正确
	**/
	isCreditCode : function (str_data) {
		let patrn = /^[0-9A-Z]+$/;
		//18位校验及大写校验
		if ((str_data.length != 18) || (patrn.test(str_data) == false)) { 
			return false;
		} else { 
			let Ancode;//统一社会信用代码的每一个值
			let Ancodevalue;//统一社会信用代码每一个值的权重 
			let total = 0; 
			let weightedfactors = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];//加权因子 
			let str = '0123456789ABCDEFGHJKLMNPQRTUWXY';
			//不用I、O、S、V、Z 
			for (let i = 0; i < str_data.length - 1; i++) {
				Ancode = str_data.substring(i, i + 1); 
				Ancodevalue = str.indexOf(Ancode); 
				total = total + Ancodevalue * weightedfactors[i];
				//权重与加权因子相乘之和 
			}
			let logiccheckcode = 31 - total % 31;
			if (logiccheckcode == 31) {
				logiccheckcode = 0;
			}
			let Str = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,W,X,Y";
			let Array_Str = Str.split(',');
			logiccheckcode = Array_Str[logiccheckcode];
			let checkcode = str_data.substring(17, 18);
			if (logiccheckcode != checkcode) { 
				return false;
			}
			return true;
		}
	},
	/**
	* @description 判断是否为银行卡号
	* @param {String} str_cardNo 待校验的数据
	* @returns {Boolean}, true:是银行卡号
	**/
	isBankCard : function (str_cardNo) {
		str_cardNo = str_cardNo || String(this);
		if ("" == str_cardNo.trim() || undefined == str_cardNo) {
			return false;
		}
		let lastNum = str_cardNo.substr(str_cardNo.length - 1, 1);//取出最后一位（与luhm进行比较）
		let first15Num = str_cardNo.substr(0, str_cardNo.length - 1);//前15或18位
		let newArr=new Array();
		for(let i=first15Num.length-1;i>-1;i--){    //前15或18位倒序存进数组
			newArr.push(first15Num.substr(i,1));
		}
		let arrJiShu=new Array();  //奇数位*2的积 <9
		let arrJiShu2=new Array(); //奇数位*2的积 >9
		let arrOuShu=new Array();  //偶数位数组
		for(let j=0;j<newArr.length;j++){
			if((j+1)%2==1){//奇数位
				if(parseInt(newArr[j])*2<9)
					arrJiShu.push(parseInt(newArr[j])*2);
				else
					arrJiShu2.push(parseInt(newArr[j])*2);
			}else{
				//偶数位
				arrOuShu.push(newArr[j]);
			}	
		}
		let jishu_child1=new Array();//奇数位*2 >9 的分割之后的数组个位数
		let jishu_child2=new Array();//奇数位*2 >9 的分割之后的数组十位数
		for(let h=0;h<arrJiShu2.length;h++){
			jishu_child1.push(parseInt(arrJiShu2[h])%10);
			jishu_child2.push(parseInt(arrJiShu2[h])/10);
		}
		let sumJiShu=0; //奇数位*2 < 9 的数组之和
		let sumOuShu=0; //偶数位数组之和
		let sumJiShuChild1=0; //奇数位*2 >9 的分割之后的数组个位数之和
		let sumJiShuChild2=0; //奇数位*2 >9 的分割之后的数组十位数之和
		let sumTotal=0;
		for(let m=0;m<arrJiShu.length;m++){
			sumJiShu=sumJiShu+parseInt(arrJiShu[m]);
		}
		for(let n=0;n<arrOuShu.length;n++){
			sumOuShu=sumOuShu+parseInt(arrOuShu[n]);
		}
		for(let p=0;p<jishu_child1.length;p++){
			sumJiShuChild1=sumJiShuChild1+parseInt(jishu_child1[p]);
			sumJiShuChild2=sumJiShuChild2+parseInt(jishu_child2[p]);
		}
		//计算总和
		sumTotal=parseInt(sumJiShu)+parseInt(sumOuShu)+parseInt(sumJiShuChild1)+parseInt(sumJiShuChild2);
		//计算Luhm值
		let k= parseInt(sumTotal)%10==0?10:parseInt(sumTotal)%10;
		let luhm= 10-k;
		if(lastNum==luhm){
			return true;
		}else{
			return false;
		}
	},
	/**
	* @description 判断数据是否为IPV4地址
	* @param {String} str_data 待校验的数据
	* @returns {Boolean}, true:是IPV4地址
	**/
	isIpV4 : function (str_data) {
		str_data = str_data || String(this)
		return ip4Reg.test(str_data)
	},
	/**
	* @description   判断数据是否为网址(URL),请传入满足http标准协议的链接
	* @param {String} str_data 待校验的数据
	* @param {Boolean} flag 是否使用严格模式,默认为false
	* @returns {Boolean}, true:是网址
	**/
	isUrl : function (str_data, flag) {
		str_data = str_data || String(this);
		flag = flag || false;
		let regular = /^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|net|org|biz|info|name|museum|asia|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$/i
		let regular2 = /^((https?|ftp):\/\/)(www\.)?\S{0,30}\.\S+$/i
	
		if (regular2.test(str_data) && !flag) {
			return true;
		} else if(regular.test(str_data) && flag) {
			return true;
		} else {
			return false;
		}
	},
	validate: function(data, rules) {
		let res = { isOk: true, errmsg: '' }
		if (!rules || !rules.length) {
			return res
		}
		for (let rule of rules) {
			// rule: {name:'', type:'', errmsg:'', min:1, max:2, eq:'', required:Boolean, regex:''}
			if (!rule || !rule.name || !rule.type) {
				continue
			}
			
			// 如果值不存在
			if (!data[rule.name]) {
				// 如果是必填项就返回错误提示，required可以作为type是为了不同的type能给用户不同的提示
				if (rule.type === 'required' || rule.required) {
					res = { isOk: false, errmsg: rule.errmsg }
					if (!res.errmsg) {
						res.errmsg = '请正确输入所有数据' //默认提示
					}
					return res
				}
				// 如果不是必填项就跳过
				continue
			}
			switch (rule.type) {
				// required 上面已经判断过了
				case 'equals':
				case 'eq':
					if (data[rule.name] !== data[rule.eqName]) {
						res = { isOk: false, errmsg: rule.errmsg }
					}
				break
				case 'number':
					if (!numberReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg }
					}
				break
				case 'int':
					if (!intReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg }
					}
				break
				case 'phone':
					if (!phoneReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg?rule.errmsg:'请输入正确的手机号码' }
					}
				break
				case 'email':
					if (!emailReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg?rule.errmsg:'请输入正确的电子邮箱' }
					}
				break
				case 'pwd':
					if (!pwdReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg }
					}
				break
				case 'inviteCode':
					if (!inviteCodeReg.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg }
					}
				break
				case 'idcard':
					if(!this.isIdcard(data[rule.name])){
						res = { isOk: false, errmsg: rule.errmsg?rule.errmsg:'请输入正确的身份证' }
					}
				break
				case 'range': // 数字类型的值取值范围
					// {name: 'xxx', type: 'range', min: 6, max: 6, required: true, errmsg: 'xxx'}
					let val = data[rule.name]
					if (val) {
						if (numberReg.test(val)) {
							if (rule.min && val < rule.min) {
								res = { isOk: false, errmsg: rule.errmsg }
							} else if (rule.max && val > rule.max) {
								res = { isOk: false, errmsg: rule.errmsg }
							}
						} else {
							res = { isOk: false, errmsg: rule.errmsg }
						}
					}
				break
				case 'lengthRange': // 字符串长度取值范围
					// {name: 'xxx', type: 'lengthRange', min: 6, max: 6, errmsg: 'xxx'}
					let le = data[rule.name] ? data[rule.name].length : 0
					if (rule.min && le < rule.min) {
						res = { isOk: false, errmsg: rule.errmsg }
					} else if (rule.max && le > rule.max) {
						res = { isOk: false, errmsg: rule.errmsg }
					}
				break
				case 'regex': // 自定义正则表达式
					// {name: 'xxx', type: 'regex', regex: /^1[0-9]{10,10}$/, errmsg: 'xxx'}
					if (rule.regex && !rule.regex.test(data[rule.name])) {
						res = { isOk: false, errmsg: rule.errmsg }
					}
				break
			}
			// 发现任何一个错误就立即返回，后面的不再判断
			if (!res.isOk) {
				if (!res.errmsg) {
					res.errmsg = '请正确输入所有数据' //默认提示
				}
				return res
			}
		}
		return res
	}
}